﻿using DGIS.GscloudService.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using DGIS.Model;
using System.Threading;

namespace DGIS.GscloudService.Service
{
    public class DownloadService : IDownloadService
    {
        //当前下载任务
        private XLEngine.DownTaskInfo downTaskInfo;

        //当前下载任务指针
        private IntPtr downTaskIntPtr;

        //当前下载文件
        private DownloadFile downloadFile;

        Func<string, int, int> downloadCallback;

        public bool AddDownloadFile(DownloadFile item, bool isResume, bool download, Func<string,int, int> callback)
        {

            downloadCallback = callback;
            downloadFile = item;

            //设置下载位置
            string fileName = item.FileName;
            string savePath = string.Format("{0}Cache\\{1}", AppDomain.CurrentDomain.BaseDirectory, String.IsNullOrEmpty(fileName) ? Guid.NewGuid().ToString() : fileName);
            item.SavePath = savePath;
            //开始下载
            try
            {
                bool xlInit = XLEngine.XL_Init();
                if (xlInit)
                {
                    downTaskInfo = new XLEngine.DownTaskInfo();
                    XLEngine.DownTaskParam downdownTaskParam = new XLEngine.DownTaskParam()
                    {
                        szTaskUrl = item.Url,
                        szFilename = System.IO.Path.GetFileName(savePath),
                        szSavePath = System.IO.Path.GetDirectoryName(savePath),
                        IsResume = isResume ? 1 : 0
                    };
                    downTaskIntPtr = XLEngine.XL_CreateTask(downdownTaskParam);
                    
                    //断点续传失败，则删除原有数据，重新下载
                    if (isResume&&downTaskIntPtr == IntPtr.Zero)
                    {
                        DelDownload(item);
                        downdownTaskParam.IsResume = 0;
                        downTaskIntPtr = XLEngine.XL_CreateTask(downdownTaskParam);                        
                    }
                    item.TaskIntPtr = downTaskIntPtr;

                    if (download && StartDownload(downTaskIntPtr))
                    {
                        downloadFile.Status = (int)DownloadFile.DownloadStatus.Downloading;
                    }
                    else
                    {
                        downloadFile.Status = (int)DownloadFile.DownloadStatus.Stop;
                    }

                    //增加下载记录
                    if (!isResume)
                        AddRecord(item);

                    //循环获取任务进度
                    Thread thread = new Thread(ShowDownTaskProgress);
                    thread.Start();

                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public List<DownloadFile> GetCompleteDownloadFiles()
        {
            DataAccessService.IService.ISqliteService sqliteService = new DataAccessService.Service.SqliteService();
            List<DownloadFile> items = sqliteService.GetList<DownloadFile>("status==3");

            return items;
        }

        public List<DownloadFile> GetResumeDownloadFiles()
        {
            DataAccessService.IService.ISqliteService sqliteService = new DataAccessService.Service.SqliteService();
            List<DownloadFile> items = sqliteService.GetList<DownloadFile>("status!=3");

            return items;
        }

        public bool StartDownload(IntPtr intPtr)
        {
            bool result = XLEngine.XL_StartTask(intPtr);
            return result;
        }

        public bool StopDownload(IntPtr intPtr)
        {
            return XLEngine.XL_StopTask(intPtr);
        }

        public bool DelDownload(DownloadFile item)
        {
            XLEngine.DownTaskParam downdownTaskParam = new XLEngine.DownTaskParam()
            {
                szTaskUrl = item.Url,
                szFilename = item.FileName,
                szSavePath = System.IO.Path.GetDirectoryName(item.SavePath)
            };
            if (StopDownload(item.TaskIntPtr) && XLEngine.XL_DeleteTask(item.TaskIntPtr) && XLEngine.XL_DelTempFile(downdownTaskParam) && DelRecord(item.DataId.ToString()))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 显示下载进度
        /// </summary>
        private void ShowDownTaskProgress()
        {
            bool taskExit = XLEngine.XL_QueryTaskInfoEx(downTaskIntPtr, downTaskInfo);

            if (!taskExit)
            {
                downloadFile.Status = (int)DownloadFile.DownloadStatus.Complete;
                return;
            }

            while (true)
            {
                downloadFile.ProgressValue = Math.Round(downTaskInfo.fPercent * 100, 2);
                downloadFile.Speed = Math.Round(downTaskInfo.nSpeed / 1024.0, 2);
                downloadFile.FileSize = downTaskInfo.nTotalSize;

                if (!XLEngine.XL_QueryTaskInfoEx(downTaskIntPtr, downTaskInfo))
                    return;

                if (downTaskInfo.stat == XLEngine.DOWN_TASK_STATUS.TSC_COMPLETE)
                {
                    downloadFile.Status = (int)DownloadFile.DownloadStatus.Complete;
                    downloadFile.Speed = 0;
                    downloadFile.ProgressValue = 100;

                    if (ModifyDownloadFile(downloadFile))
                    {
                        downloadCallback(downloadFile.DataId, (int)downloadFile.Status);
                    }

                    return;
                }
                else if (downTaskInfo.stat == XLEngine.DOWN_TASK_STATUS.TSC_ERROR)
                {
                    downloadFile.Status = (int)DownloadFile.DownloadStatus.Error;
                    downloadCallback(downloadFile.DataId, (int)downloadFile.Status);
                    return;
                }
                else if (downTaskInfo.stat == XLEngine.DOWN_TASK_STATUS.TSC_PAUSE || downTaskInfo.stat == XLEngine.DOWN_TASK_STATUS.TSC_STOPPENDING)
                {
                    downloadFile.Status = (int)DownloadFile.DownloadStatus.Stop;
                    downloadCallback(downloadFile.DataId, (int)downloadFile.Status);
                }

                Thread.Sleep(1000*2);
            }
        }

        /// <summary>
        /// 新增下载记录
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private bool AddRecord(DownloadFile item)
        {
            DataAccessService.IService.ISqliteService sqliteService = new DataAccessService.Service.SqliteService();
            return sqliteService.AddItem<DownloadFile>(item, "Id");
        }

        /// <summary>
        /// 删除任务
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DelRecord(string id)
        {
            DataAccessService.IService.ISqliteService sqliteService = new DataAccessService.Service.SqliteService();
            return sqliteService.DeleteItem("DownloadFile", "dataId", id);
        }

        public bool ModifyDownloadFile(DownloadFile item)
        {
            DataAccessService.IService.ISqliteService sqliteService = new DataAccessService.Service.SqliteService();
            return sqliteService.UpdateItem<DownloadFile>(item, "DataId", item.DataId);
        }
    }
}
